package hn.cch.service.ipml;

import hn.cch.entity.Order;
import hn.cch.entity.Product;
import hn.cch.entity.User;
import hn.cch.message.Request;
import hn.cch.message.Response;
import hn.cch.repository.OrderRepository;
import hn.cch.service.OrderService;
import hn.cch.service.ProductService;
import hn.cch.service.UserService;
import io.seata.spring.annotation.GlobalTransactional;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.client.RestTemplate;

import java.util.Optional;


@Service
public class OrderServiceImpl implements OrderService {

    private static Logger logger = LoggerFactory.getLogger(OrderServiceImpl.class);


    @Autowired
    private OrderRepository orderRepository;

    @Autowired
    private UserService userService;

    @Autowired
    private ProductService productService;


    // @Autowired
    // private RestTemplate restTemplate;
    //
    // @Autowired
    // private DiscoveryClient discoveryClient;


    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    public Order findById(Integer id) {
        Optional<Order> optional = orderRepository.findById(id);
        return optional.isPresent() ? optional.get() : null;
    }


    public Order save(Order order) {
        return orderRepository.save(order);
    }


    /**
     * 下单
     *
     * @return
     */
    @GlobalTransactional
    public boolean placeOrder(Order order) {

        //调用商品服务减少库存
        Response<Product> productResponse = productService.subAny(order.getProductId(), order.getBuyCount());
        if (Response.SUCCESS.equals(productResponse.getCode())) {
            //订单入库
            save(order);
            logger.info("订单入库成功");
            return true;
        } else {
            logger.error("减少库存出错");
        }
        return false;

    }


    /**
     * 校验数据
     *
     * @param request
     * @return
     */
    public Response<Order> addOne(Request<Order> request) {

        Order order = request.getData();

        if (order == null) {
            logger.error("订单对象为空");
            return Response.failure();
        }

        if (findById(order.getOrderId()) != null) {
            logger.error("订单编号重复");
            return Response.failure();
        }

        // 设置请求网址
        // String userGetOne = "http://localhost:8880/user/getOne/"+order.getUserId();
        // String productGetOne = "http://localhost:8884/product/getOne/" + order.getProductId();
        // 设置服务名称
        // String userServiceName = "shop-user";
        // String productServiceName = "shop-product";
        //使用nacos获取对应服务列表中的第一个服务的主机和端口
        // ServiceInstance userServiceInstance = discoveryClient.getInstances(userServiceName).get(0);
        // ServiceInstance productServiceInstance = discoveryClient.getInstances(productServiceName).get(0);
        // logger.info("service user url:{}", userServiceInstance.getHost() + ":" + userServiceInstance.getPort());
        // logger.info("service product url:{}", productServiceInstance.getHost() + ":" + productServiceInstance.getPort());
        // String userGetOne = "http://" + userServiceInstance.getHost() + ":" + userServiceInstance.getPort() + "/user/getOne/" + order.getUserId();
        // String productGetOne = "http://" + productServiceInstance.getHost() + ":" + productServiceInstance.getPort() + "/product/getOne/" + order.getProductId();
        //引入ribbon使用服务名称获取服务的主机和端口
        // String userGetOne = "http://" + userServiceName + "/user/getOne/" + order.getUserId();
        // String productGetOne = "http://" + productServiceName + "/product/getOne/" + order.getProductId();
        // 使用RestTemplate
        // User user = restTemplate.getForObject(userGetOne, User.class);
        // Product product = restTemplate.getForObject(productGetOne, Product.class);

        // 使用feign（集成ribbon）
        User user = userService.getOne(order.getUserId());
        Product product = productService.getOne(order.getProductId());

        // 服务容错
        if (user.getUserId() == -1) {
            logger.error("用户服务繁忙");
            return Response.failure();
        }
        if (product.getProductId() == -1) {
            logger.error("商品服务繁忙");
            return Response.failure();
        }

        // 结账计算
        order.setBuyMoney(user.getUserDiscount() * product.getProductPrice() * order.getBuyCount());


        //下单操作使用事务机制处理
        if (placeOrder(order)) {
            return Response.failure();
        }


        // 下单成功之后使用消息队列通知用户模块扣除余额
        rocketMQTemplate.convertAndSend("order-topic", order);

        //消息队列发布消息
        // rocketMQTemplate.sendOneWay("order-topic", order);//单向发送
        // rocketMQTemplate.syncSend("order-topic", order);//同步发送
        //异步发送
        // rocketMQTemplate.asyncSend("order-topic", order, new SendCallback() {
        //     @Override
        //     public void onSuccess(SendResult sendResult) {
        //         logger.debug("onSuccess:{}", sendResult);
        //     }
        //
        //     @Override
        //     public void onException(Throwable throwable) {
        //         logger.error("onException:{}", throwable);
        //     }
        // });


        //顺序性：方法后面加上Orderly  同步异步类似
        // rocketMQTemplate.sendOneWayOrderly("order-topic", order, order.getOrderId().toString());//单向发送

        //事务性：


        logger.info("创建订单成功");
        Response response = Response.success();
        response.setInfo(order);
        return response;
    }


}
